<?php
class Pageley_Domain_Validator_File extends Pageley_Domain_Validator_Abstract {
	
    private $invalidMimeTypeMessage = "error.validation.invalidMimeType";
    private $fileTooLargeMessage = "error.validation.fileTooLarge";
    private $fileTooLargeSizeUnknownMessage = "error.validation.fileTooLargeSizeUnknown";
    private $maxSize;
	private $mimeTypes;
	
	public function validate($value, $propertyName, $object) {
		$errors = new Pageley_Util_ArrayMap();
		if($value !== null) {
		    $uploadInfo = $value->getUploadInfo();
			$size = round($uploadInfo["size"] / 1024, 0);
			$type = $uploadInfo["type"];
            $error = $uploadInfo["error"];
            $maxSize = round($this->maxSize / 1024, 0);
			$tooLarge = $this->rejectIfTrue($error != UPLOAD_ERR_OK, $this->fileTooLargeSizeUnknownMessage, array("{field." . $propertyName . "}", $maxSize));
		    if($tooLarge) {
                $errors->put($propertyName, $tooLarge);
            }
			$tooLarge = $this->rejectIfGreater($size, $maxSize, $propertyName, $this->fileTooLargeMessage);
            if($tooLarge) {
                $errors->put($propertyName, $tooLarge);
            }
            $invalidType = $this->rejectIfFalse($this->mimeTypes->containsValue($type), $this->invalidMimeTypeMessage, array("{field." . $propertyName . "}", $type, $this->toString($this->mimeTypes)));
            if($invalidType) {
                $errors->put($propertyName, $invalidType);
            }
            if($errors->isEmpty()) {
                $location = $value->getLocation();
                $category = Pageley_Util_String::substringBefore($location, "/");
                $fileManager = $value->getFileManager();
                $targetFile = new Pageley_Util_File($fileManager->getDirectory() . $location);
                $fileNameWithoutExtension = $targetFile->getNameWithoutExtension();
                $extension = $targetFile->getExtension();
                $i = 1;
                while($targetFile->exists()) {
                    $i++;
                    $location = $category . "/" . $fileNameWithoutExtension . "-" . $i . $extension;
                    $targetFile = new Pageley_Util_File($fileManager->getDirectory() . $location);
                }
                $directory = $targetFile->getParent();
                if(!$directory->exists()) {
                    $directory->createDirectory();
                }
                move_uploaded_file($uploadInfo["tmp_name"], $targetFile->getPath());
                $value->setLocation($location);
            }
        }
		return $errors;
	}
	
	public function setInvalidMimeTypeMessage($invalidMimeTypeMessage) {
        $this->invalidMimeTypeMessage = $invalidMimeTypeMessage;
    }

    public function setFileTooLargeMessage($fileTooLargeMessage) {
        $this->fileTooLargeMessage = $fileTooLargeMessage;
    }

    public function setFileTooLargeSizeUnknownMessage($fileTooLargeSizeUnknownMessage) {
        $this->fileTooLargeSizeUnknownMessage = $fileTooLargeSizeUnknownMessage;
    }

    public function setRequiredMessage($requiredMessage) {
        $this->requiredMessage = $requiredMessage;
    }

    public function setMaxSize($maxSize) {
        $this->maxSize = $maxSize;
    }

    public function setMimeTypes($mimeTypes) {
        $this->mimeTypes = $mimeTypes;
    }
    
    private function toString($mimeTypes) {
        $string = "";
        foreach($mimeTypes as $type) {
            if($string != "") {
                $string .= ", ";
            }
            $string .= $type;
        }
        return $string;
    }
}